<?php
/**
 * 数据库操作类
 *
 * @author vincent
 *        
 */
class Database {
	/**
	 * 实例
	 *
	 * @var Database
	 */
	private static $_instance = NULL;
	/**
	 * pdo对象
	 *
	 * @var PDO
	 */
	protected $pdo = NULL;
	/**
	 * 构造函数
	 */
	private function __construct() {
		$config = &$GLOBALS ['CONFIG'];
		$options = array (
				// 设置字符集
				PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES ' . $config ['DB_CHARSET'],
				// 不使用PHP本地模拟prepare
				PDO::ATTR_EMULATE_PREPARES => false,
				// 设置默认的提取模式为关联数组
				PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
				// 设置错误处理的模式为抛出异常
				PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION 
		);
		$dsn = sprintf ( "%s:dbname=%s;host=%s", $config ['DB_TYPE'], $config ['DB_NAME'], $config ['DB_HOST'] );
		$this->pdo = new PDO ( $dsn, $config ['DB_USER'], $config ['DB_PWD'], $options );
	}
	/**
	 * 获取数据库操作对象实例
	 *
	 * @return Database
	 */
	public static function getInstance() {
		if (self::$_instance == NULL) {
			self::$_instance = new Database ();
		}
		return self::$_instance;
	}
	/**
	 * 设置要进行操作的表名
	 *
	 * @param string $table
	 */
	public function setTable($table) {
		$this->table = $table;
	}
	
	/**
	 * 获取pdo实例
	 *
	 * @return PDO
	 */
	public function getPDO() {
		return $this->pdo;
	}
	/**
	 * 执行sql语句
	 *
	 * @param string $sql
	 * @param array $bind
	 */
	public function exec($sql, $bind = array()) {
		return $this->executePrepareSQL ( $sql, $bind );
	}
	/**
	 * 执行sql语句 返回结果集
	 *
	 * @param string $sql
	 * @param array $bind
	 * @return mixed
	 */
	public function query($sql, $bind = array()) {
		return $this->executePrepareSQL ( $sql, $bind, true );
	}
	/**
	 * 开始事务
	 */
	public static function beginTransaction() {
		$db = self::getInstance ();
		$db->pdo->setAttribute ( PDO::ATTR_AUTOCOMMIT, false );
		$db->pdo->beginTransaction ();
	}
	/**
	 * 提交事务
	 */
	public static function commit() {
		$db = self::getInstance ();
		$db->pdo->commit ();
		$db->pdo->setAttribute ( PDO::ATTR_AUTOCOMMIT, true );
	}
	/**
	 * 回滚事务
	 */
	public static function rollBack() {
		$db = self::getInstance ();
		$db->pdo->rollBack ();
		$db->pdo->setAttribute ( PDO::ATTR_AUTOCOMMIT, true );
	}
	/**
	 * 执行预编译sql
	 *
	 * @param string $sql 预编译sql语句
	 * @param data $bind 绑定参数
	 * @param boolean $isSelect是否为select语句
	 */
	public function executePrepareSQL($sql, $bind = array(), $isSelect = false) {
		$statment = $this->pdo->prepare ( $sql );
		foreach ( $bind as $name => $value ) {
			$statment->bindValue ( $name, $value ); // 这里不能使用bindParam
		}
		$result = $statment->execute ();
		if (! $isSelect) {
			return $result;
		}
		return $statment->fetchAll ();
	}
}

